home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Think Class Libraries / Item Class / Item sources / CDragDropTableTask.c next >
Encoding:
C/C++ Source or Header  |  1994-11-30  |  6.0 KB  |  259 lines  |  [TEXT/KAHL]

  1. /*
  2.  * File:        CDragDropTableTask.c
  3.  * Created:        8/1/93
  4.  * Desc:        A mousetask that handles dragging and dropping
  5.  *                in CItemTable.
  6.  *
  7.  * Superclass:    CTableDragger.
  8.  * Uses:        CItemTable, CItem.
  9.  * Original Author:    W. Wesley Monroe
  10.  * Modifications:    
  11.  *
  12.  * Copyright © 1993 Animas Software Production. All rights reserved.
  13.  */
  14.  
  15. #include "CDragDropTableTask.h"
  16. #include "CItemTable.h"
  17. #include "CItemList.h"
  18. #include "LongQD.h"
  19. #include "CItem.h"
  20.  
  21. extern CBureaucrat *gGopher;
  22.  
  23. void CDragDropTableTask::IDragDropTableTask(CTable *aTable,
  24.                                             CView *dragBoundsPane,
  25.                                             short theModifiers,
  26.                                             long selFlags)
  27. {
  28.     ITableDragger(aTable, theModifiers, selFlags);
  29.  
  30.     fCanDragDrop = (selCanDrag & selFlags) | (selCanRecieve & selFlags);
  31.  
  32.     fEnclosingPano = dragBoundsPane;
  33.     fDropTarget = FALSE;
  34.     fGRDrawn = FALSE;
  35.     fFirst = TRUE;
  36.     fGrayRgn = 0;
  37.     fReleasedView = fOriginalView = aTable;
  38.     
  39.     fSelectedItems = 0L;
  40. }
  41.  
  42. void CDragDropTableTask::Dispose(void)
  43. {
  44.     ForgetObject(fSelectedItems);
  45.  
  46.     inherited::Dispose();
  47. }
  48.  
  49. void CDragDropTableTask::BeginTracking(LongPt *startPt)
  50. {
  51.     Cell        hitCell;
  52.     RgnHandle    aRgn;
  53.  
  54.     itsTable->FindHitCell(startPt, &hitCell);
  55.  
  56.     fDropTargetCell = hitCell;
  57.         // Call Begin Tracking only if modifierkeys are down,
  58.         // or the hitCell is not Selected.....
  59.     if(modifierKeys || !itsTable->IsSelected(hitCell))
  60.         inherited::BeginTracking(startPt);
  61.  
  62.     fSelectedItems = ((CItemTable *) itsTable)->GetHiliteRgn(&aRgn);
  63.     fGrayRgn = aRgn;
  64. }
  65.  
  66. void CDragDropTableTask::KeepTracking(LongPt *currPt, LongPt *prevPt,
  67.                                       LongPt *startPt)
  68. {
  69.     CView        *theDropInView;
  70.     CView        *enclView = fEnclosingPano;
  71.     CItemTable    *dropInTable;
  72.  
  73.     PenState    saveState;
  74.     RgnHandle    aRgn = fGrayRgn;
  75.     Point    scp;
  76.     Cell    hitCell;
  77.     Rect    r, r2;
  78.     Point    cp;
  79.  
  80.     GetPenState(&saveState);
  81.  
  82.     if(fFirst && !EqualLongPt(currPt, prevPt)) {
  83.         PenPat(gray);
  84.         PenMode(srcXor);
  85.         FrameRgn(aRgn);
  86.         fFirst = FALSE;
  87.         fGRDrawn = TRUE;
  88.     } else if(!EqualLongPt(currPt, prevPt)) {
  89.         PenPat(gray);
  90.         PenMode(srcXor);
  91.         FrameRgn(aRgn);
  92.         OffsetRgn(aRgn, (short) (currPt->h - prevPt->h),
  93.                   (short) (currPt->v - prevPt->v));
  94.         FrameRgn(aRgn);
  95.         fGRDrawn = TRUE;
  96.         fFirst = FALSE;
  97.  
  98.         ASSERT(fEnclosingPano);
  99.  
  100.         scp.h = currPt->h - enclView->macPort->portRect.left;
  101.         scp.v = currPt->v - enclView->macPort->portRect.top;
  102.         
  103. //        ((CPane*)fEnclosingPano)->FrameToWind(currPt, &scp);
  104.         theDropInView = enclView->FindSubview(scp);
  105.         
  106.         if(theDropInView) {
  107.  
  108.                 // For now, the only panes that can recieve are ScrollPanes
  109.                 // with ItemTables en em...
  110.             if(member(theDropInView, CScrollPane)) {                
  111.                 dropInTable = (CItemTable *)
  112.                             ((CScrollPane *) theDropInView)->itsPanorama;
  113.             } else if(member(theDropInView, CItemTable))
  114.                 dropInTable = (CItemTable *) theDropInView;
  115.             else
  116.                 return;
  117.  
  118.             if(dropInTable && dropInTable->GetCanRecieve()) {
  119.                 LongPt    p;
  120.  
  121.                 fReleasedView = dropInTable;
  122.                     // Make the table the gopher...
  123.                 if(gGopher != dropInTable)
  124.                     dropInTable->BecomeGopher(TRUE);
  125.  
  126.                 if(dropInTable != fOriginalView) {
  127.  
  128.                     dropInTable->WindToFrame(scp, &p);
  129.                     dropInTable->FindHitCell(&p, &hitCell);
  130.  
  131.                 } else
  132.                     dropInTable->FindHitCell(currPt, &hitCell);
  133.  
  134.                 r.top = hitCell.v; r.left = hitCell.h;
  135.                 r.bottom = r.top + 1;
  136.                 r.right = r.left + 1;
  137.                 if((dropInTable != fOriginalView) || !PtInRect(fDropTargetCell, &r)) {
  138.  
  139.                         // Only deselect if it was already selected
  140.                     if(fDropTarget) {
  141.                         fDropTarget = FALSE;
  142.                         r2.top = fDropTargetCell.v;
  143.                         r2.left = fDropTargetCell.h;
  144.                         r2.bottom = r2.top + 1;
  145.                         r2.right = r2.left + 1;
  146.                         dropInTable->Hilite(&r2, FALSE);
  147.                     }
  148.  
  149.                     if(!dropInTable->HitInDrag(hitCell)
  150.                          && dropInTable->ItemCanAcceptDrop(hitCell, fSelectedItems)) {
  151.                             // Hilite the new one
  152.                         dropInTable->Hilite(&r, TRUE);
  153.                         fDropTarget = TRUE;
  154.                     }
  155.                     fDropTargetCell = hitCell;
  156.                 }
  157.             }
  158.         }
  159.     }
  160.  
  161.     itsTable->AutoScroll( currPt);
  162.     fGrayRgn = aRgn;
  163.     SetPenState(&saveState);
  164. }
  165.  
  166. void CDragDropTableTask::EndTracking(LongPt *currPt, LongPt *prevPt,
  167.                                      LongPt *startPt)
  168. {
  169.     CItemList    *selList;
  170.  
  171.     Cell dropCell = {0, 0};
  172.     Cell        hitCell;
  173.     PenState    saveState;
  174.     RgnHandle    aRgn = fGrayRgn;
  175.  
  176.         // Erase the last gray region...
  177.     if(fGRDrawn) {
  178.  
  179.         GetPenState(&saveState);
  180.     
  181.         PenPat(gray);
  182.         PenMode(srcXor);
  183.         OffsetRgn(aRgn, (short) (currPt->h - prevPt->h),
  184.                   (short) (currPt->v - prevPt->v));
  185.         FrameRgn(aRgn);
  186.     
  187.         SetPenState(&saveState);
  188.     }
  189.         // Region be gone...
  190.     DisposeRgn(aRgn);
  191.     fGrayRgn = 0L;
  192.     
  193.     ASSERT(fReleasedView);
  194.  
  195.     selList = fSelectedItems;
  196.  
  197.     /*
  198.      * See if items were dropped in a ItemTable or one of its
  199.      * subclasses.
  200.      */
  201.  
  202.     if(member(fReleasedView, CItemTable)) {
  203.  
  204.         CItem        *firstSelItem, *dropTargetItem;
  205.         CItemList    *copy;
  206.         CItemTable *targetList = (CItemTable *) fReleasedView;
  207.         CItemTable *originalList = (CItemTable *) fOriginalView;
  208.  
  209.         targetList->FindHitCell(startPt, &hitCell);
  210.  
  211.             // Which cell was the item dropped in...
  212.         targetList->FindHitCell(currPt, &dropCell);
  213.  
  214.  
  215.         if(dropCell.v >= 0)
  216.             dropTargetItem = targetList->GetItem(dropCell.v + 1);
  217.         else
  218.             dropTargetItem = 0L;
  219.  
  220.         /*
  221.          * If they clicked and released in the same cell, and
  222.          * that cell is not a root object, and the option key
  223.          * is down, move the item to the top of the tree.
  224.          */
  225.          
  226.          if(hitCell.v ==  dropCell.v) {
  227.             if(modifierKeys & optionKey    && dropTargetItem->GetLevel() != 0) {
  228.     
  229.                     // Remove an item to the top of the hierarchy...
  230.                 targetList->RemoveSubviews(selList);
  231.     
  232.                 targetList->GraftItems(0L, selList);
  233.             }
  234.             return;
  235.         }
  236.  
  237.         firstSelItem = (CItem *) selList->FirstItem();
  238.  
  239.         /*
  240.          * If they did not drop in the same cell or
  241.          * they dropped in a different view, remove the items
  242.          * from the original list and graft them under the
  243.          * target item.
  244.          */
  245.  
  246. /*        if((hitCell.v + 1 !=  dropCell.v  || t != t2 ) &&*/
  247. /*                            !t2->DropedSameParent(dropCell.v,*/
  248. /*                                                 firstSelItem)) {*/
  249. /*        if(hitCell.v + 1 !=  dropCell.v  ||*/
  250. /*                     targetList != originalList) {*/
  251.  
  252.         if(dropCell.v <= 0 || targetList->ItemCanAcceptDrop(dropCell, selList)) {
  253.  
  254.             originalList->RemoveSubviews(selList);            
  255.             targetList->GraftItems(dropTargetItem, selList);
  256.         }
  257.     }
  258. }
  259.